<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>PlPN - Perl Plugin for Programmer's Notepad</title>
<link rel="stylesheet" href="PlPN.css" type="text/css" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:" />
</head>

<body>


<!-- INDEX BEGIN -->
<div name="index">
<p><a name="__index__"></a></p>

<ul>

	<li><a href="#name">NAME</a></li>
	<li><a href="#synopsis">SYNOPSIS</a></li>
	<li><a href="#description">DESCRIPTION</a></li>
	<ul>

		<li><a href="#cycling_the_interpreter">Cycling the interpreter</a></li>
		<li><a href="#customization">Customization</a></li>
	</ul>

	<li><a href="#versions">VERSIONS</a></li>
	<li><a href="#exports">EXPORTS</a></li>
	<li><a href="#methods">METHODS</a></li>
	<li><a href="#events">EVENTS</a></li>
	<li><a href="#utility_methods">UTILITY METHODS</a></li>
	<li><a href="#utility_functions">UTILITY FUNCTIONS</a></li>
	<li><a href="#copyright_and_licence">COPYRIGHT and LICENCE</a></li>
</ul>

<hr name="index" />
</div>
<!-- INDEX END -->

<p>
</p>
<h1><a name="name">NAME</a></h1>
<p>PlPN - Perl Plugin for Programmer's Notepad</p>
<p>
</p>
<hr />
<h1><a name="synopsis">SYNOPSIS</a></h1>
<pre>
        use PlPN;
        
        PlPN-&gt;RegisterEvent($event_name, $subref);
        PlPN-&gt;RegisterScript($group, $name, $subref);
        
        # etc.</pre>
<p>
</p>
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p>Implements a Perl interface to Programmer's Notepad.</p>
<p>Basic objects:</p>
<ul>
<li><strong><a name="plpn_pn_plpn_pn_the_progammer_s_notepad_object" class="item"><a href="PlPN/PN.html">PlPN::PN</a> - The Progammer's Notepad object</a></strong>

</li>
<li><strong><a name="plpn_document_plpn_document_the_document_object" class="item"><a href="PlPN/Document.html">PlPN::Document</a> - The document object</a></strong>

</li>
<li><strong><a name="plpn_options_plpn_options_the_options_manager_object" class="item"><a href="PlPN/Options.html">PlPN::Options</a> - The options manager object</a></strong>

</li>
<li><strong><a name="plpn_searchoptions_plpn_searchoptions_the_search_options_object" class="item"><a href="PlPN/SearchOptions.html">PlPN::SearchOptions</a> - The search options object</a></strong>

</li>
<li><strong><a name="plpn_textoutput_plpn_textoutput_the_text_output_window_object" class="item"><a href="PlPN/TextOutput.html">PlPN::TextOutput</a> - The text output window object</a></strong>

</li>
</ul>
<p>If the default implementation is not sufficient for you, the following
objects can give you finer-grained control over events and scripts:</p>
<ul>
<li><strong><a name="plpn_appeventsink_plpn_appeventsink_the_application_event_sink" class="item"><a href="PlPN/AppEventSink.html">PlPN::AppEventSink</a> - The application event
sink</a></strong>

</li>
<li><strong><a name="plpn_documenteventsink_plpn_documenteventsink_the_document_event_sink" class="item"><a href="PlPN/DocumentEventSink.html">PlPN::DocumentEventSink</a> - The document
event sink</a></strong>

</li>
<li><strong><a name="plpn_texteditoreventsink_plpn_texteditoreventsink_the_text_editor_event_sink" class="item"><a href="PlPN/TextEditorEventSink.html">PlPN::TextEditorEventSink</a> - The text
editor event sink</a></strong>

</li>
<li><strong><a name="plpn_scriptregistry_plpn_scriptregistry_the_script_registry_object" class="item"><a href="PlPN/ScriptRegistry.html">PlPN::ScriptRegistry</a> - The script registry
object</a></strong>

</li>
<li><strong><a name="plpn_scriptrunner_plpn_scriptrunner_the_script_runner_object" class="item"><a href="PlPN/ScriptRunner.html">PlPN::ScriptRunner</a> - The script runner object</a></strong>

</li>
<li><strong><a name="plpn_recorder_plpn_recorder_the_macro_recorder_object" class="item"><a href="PlPN/Recorder.html">PlPN::Recorder</a> - The macro recorder object</a></strong>

</li>
</ul>
<p>It is also possible to add menu items in Programmer's Notepad, under the
<code>Extensions</code> menu:</p>
<ul>
<li><strong><a name="plpn_menu_plpn_menu_the_menu_object" class="item"><a href="PlPN/Menu.html">PlPN::Menu</a> - The menu object</a></strong>

</li>
</ul>
<p>
</p>
<h2><a name="cycling_the_interpreter">Cycling the interpreter</a></h2>
<p>The plugin gives Programmer's Notepad users the chance to cycle the Perl
interpreter. There are two reasons for this. First, if the Perl interpreter
has been running for a while, it may be using a lot of memory and slowing
down Programmer's Notepad. Cycling allows that memory to be released without
shutting down and restarting the entire program. Second, it allows for the
development of scripts without shutting down and restarting the entire
program, since every time the interpreter is cycled, the scripts are reread.</p>
<p>However, since cycling involves deleting and recreating the Perl
interpreter, all Perl variables are lost. Two options have been provided for
preserving your data. The simpler option is the <a href="#registerdata">RegisterData</a> method.
For more control, the <a href="#onbeforecycle">OnBeforeCycle</a> and <a href="#onaftercycle">OnAfterCycle</a>
events and the <a href="#currentdocuments">CurrentDocuments</a> method are also provided.</p>
<p>
</p>
<h2><a name="customization">Customization</a></h2>
<p>After loading <em class="file">PlPN.pm</em>, but before loading any script files, the file
<em class="file">plpn.init</em> in the scripts folder will be loaded. This is your chance to
customize the object, including replacing this default implementation with
your own object.</p>
<p>To do so, first create your object. For ease, you will probably want to
inherit from <code>PlPN</code>, but this is not required. Then set the variable
<code>$PlPN::PlPN</code> to an instance of your object, or if you have implemented
your implementation via class methods (like this default implementation
does), with your class name.</p>
<p>Note that if you do not inherit from <code>PlPN</code>, you <strong>must</strong> implement all the
methods listed below, since scripts may depend on them.</p>
<p>In addition, if <em class="file">plpn.init</em> returns a defined false value, no scripts will
be loaded. This allows you to replace the default script loading
implementation with your own. The scalar <code>$PlPN::ScriptsFolder</code> will
contain the path to the default script folder.</p>
<p>Note that the function that loads scripts returns <code>undef</code> on error, so you
must return a I<em>defined</em> false value to cancel script loading.</p>
<p>
</p>
<hr />
<h1><a name="versions">VERSIONS</a></h1>
<p>This package has two version variables. <code>$PlPN::PluginVersion</code> is the
version of the C++/XS plugin (<em class="file">PlPN.dll</em>). <code>$PlPN::ModuleVersion</code> is the
version of the Perl module (<em class="file">PlPN.pm</em>).</p>
<p>
</p>
<hr />
<h1><a name="exports">EXPORTS</a></h1>
<p>Nothing is exported by default.</p>
<dl>
<dt><strong><a name="pn" class="item">PN</a></strong></dt>

<dd>
<p>The <a href="PlPN/PN.html">PlPN::PN</a> object, which allows access to Programmer's
Notepad.</p>
</dd>
<dt><strong><a name="pn_ext_iface_version" class="item">PN_EXT_IFACE_VERSION</a></strong></dt>

<dd>
<p>The extension interface version. Probably not very useful for Perl programs,
but provided for the sake of completeness.</p>
</dd>
<dt><strong><a name="true" class="item">TRUE</a></strong></dt>

<dt><strong><a name="false" class="item">FALSE</a></strong></dt>

<dd>
<p>The special Perl values for true and false. Used with
<a href="PlPN/Options.html#set">PlPN::Options::Set</a> and
<a href="PlPN/Options.html#get">PlPN::Options::Get</a>.</p>
</dd>
<dt><strong><a name="eexecflags" class="item">:EExecFlags</a></strong></dt>

<dd>
<p>Execution flags for <a href="PlPN/ScriptRunner.html#exec">PlPN::ScriptRunner::Exec</a>.</p>
</dd>
<dt><strong><a name="efiffileset" class="item">:EFIFFileSet</a></strong></dt>

<dd>
<p>File sets for <a href="PlPN/SearchOptions.html">PlPN::SearchOptions</a>.</p>
</dd>
<dt><strong><a name="efindwhere" class="item">:EFindWhere</a></strong></dt>

<dd>
<p>Targets for <a href="PlPN/SearchOptions.html">PlPN::SearchOptions</a>.</p>
</dd>
<dt><strong><a name="emenuitemtype" class="item">:EMenuItemType</a></strong></dt>

<dd>
<p>Menu item types for <a href="PlPN/Menu.html">PlPN::Menu</a>.</p>
</dd>
<dt><strong><a name="findnextresult" class="item">:FindNextResult</a></strong></dt>

<dd>
<p>Result indicators for <a href="PlPN/PN.html#findnext">PlPN::PN::FindNext</a> and
<a href="PlPN/RecorderRecordSearchAction.html">PlPN::Recorder::RecordSearchAction</a>.</p>
</dd>
<dt><strong><a name="searchtype" class="item">:SearchType</a></strong></dt>

<dd>
<p>Search type indicators for
<a href="PlPN/Recorder.html#recordsearchaction">PlPN::Recorder::RecordSearchAction</a>.</p>
</dd>
<dt><strong><a name="pnpath" class="item">:PNPath</a></strong></dt>

<dd>
<p>Path indicator for <a href="PlPN/Options.html#getpnpath">PlPN::Options::GetPNPath</a>.</p>
</dd>
<dt><strong><a name="optionsgroup" class="item">:OptionsGroup</a></strong></dt>

<dd>
<p>Group names for <a href="PlPN/Options.html#set">PlPN::Options::Set</a>,
<a href="PlPN/Options.html#get">PlPN::Options::Get</a>,
<a href="PlPN/Options.html#begingroupoperation">PlPN::Options::BeginGroupOperation</a>, and
<a href="PlPN/Options.html#endgroupoperation">PlPN::Options::EndGroupOperation</a>.</p>
</dd>
<dt><strong><a name="ecachedoption" class="item">:ECachedOption</a></strong></dt>

<dd>
<p>Option indicators for <a href="PlPN/Options.html#getcached">PlPN::Options::GetCached</a>
and <a href="PlPN/Options.html#setcached">PlPN::Options::SetCached</a>.</p>
</dd>
</dl>
<p>
</p>
<hr />
<h1><a name="methods">METHODS</a></h1>
<dl>
<dt><strong><a name="registerevent" class="item">RegisterEvent($event, $subref)</a></strong></dt>

<dt><strong><a name="unregisterevent" class="item">UnregisterEvent($event, $subref)</a></strong></dt>

<dd>
<p>Registers an event with the system. Multiple subrefs can be registered to
the same event. The following events are available:</p>
<dl>
<dt><strong><a name="onbeforecycle" class="item">OnBeforeCycle()</a></strong></dt>

<dt><strong><a name="onaftercycle" class="item">OnAfterCycle()</a></strong></dt>

<dd>
<p>Called before and after the Perl interpreter is cycled.</p>
</dd>
<dt><strong><a name="onnewdocument" class="item">OnNewDocument($doc)</a></strong></dt>

<dd>
<p>Called whenever a new document is opened.</p>
</dd>
<dt><strong><a name="appclose" class="item">AppClose()</a></strong></dt>

<dd>
<p>Called when Programmer's Notepad is about to close.</p>
</dd>
<dt><strong><a name="ondocselected" class="item">OnDocSelected($doc)</a></strong></dt>

<dd>
<p>Called whenever a document is made the active document.</p>
</dd>
<dt><strong><a name="onfirsteditorcreated" class="item">OnFirstEditorCreated($scintilla_window_handle)</a></strong></dt>

<dd>
<p>Called when the first Scintilla window is created. The extensions
documentation indicates that this is useful for loading external lexers.
It's probably not very useful for Perl programs, but it is included for the
sake of completeness.</p>
</dd>
<dt><strong><a name="onschemechange" class="item">OnSchemeChange($doc, $scheme)</a></strong></dt>

<dd>
<p>Called whenever a document's scheme is changed.</p>
</dd>
<dt><strong><a name="ondocclosing" class="item">OnDocClosing($doc)</a></strong></dt>

<dd>
<p>Called whenever a document is closed.</p>
</dd>
<dt><strong><a name="onafterload" class="item">OnAfterLoad($doc)</a></strong></dt>

<dd>
<p>Called after a document has been loaded.</p>
</dd>
<dt><strong><a name="onbeforesave" class="item">OnBeforeSave($doc, $filename)</a></strong></dt>

<dd>
<p>Called when a document is about to be saved.</p>
</dd>
<dt><strong><a name="onaftersave" class="item">OnAfterSave($doc)</a></strong></dt>

<dd>
<p>Called after a document has been saved.</p>
</dd>
<dt><strong><a name="onmodifiedchanged" class="item">OnModifiedChanged($doc, $modified)</a></strong></dt>

<dd>
<p>Called when a document has changed its modified state.</p>
</dd>
<dt><strong><a name="onwriteprotectchanged" class="item">OnWriteProtectChanged($doc, $protected)</a></strong></dt>

<dd>
<p>Called when a document has changed its write-protect state.</p>
</dd>
<dt><strong><a name="oncharadded" class="item">OnCharAdded($doc, $char)</a></strong></dt>

<dd>
<p>Called when a character is added to a document. The character passed in will
be a utf8 string. This is not called when text is pasted into a document, or
when control characters (such as backspace) are entered.</p>
</dd>
</dl>
</dd>
<dt><strong><a name="registerscript" class="item">RegisterScript($group, $name, $subref)</a></strong></dt>

<dd>
<p>Registers a script. <code>$group</code> is optional and will default to <code>perl</code>.</p>
<p>In the Programmer's Notepad Scripts window, <code>$group</code> is the parent node and
<code>$name</code> is the child node under it; double-clicking <code>$name</code> will call
<code>$subref</code>.</p>
<p>The extensions interface does not allow the unregistering of a script. Even
if the script is removed and the Perl interpreter is cycled, the entry in
the Scripts window will remain, and a message indicating the script has been
removed will appear if the user tries to run the script.</p>
</dd>
<dt><strong><a name="registerdata" class="item">RegisterData($varname)</a></strong></dt>

<dt><strong><a name="unregisterdata" class="item">UnregisterData($varname)</a></strong></dt>

<dd>
<p>Registers a variable with the system so that it is preserved during cycling.
<code>$varname</code> should be a fully-qualified variable name, with sigil.
Individual elements from arrays and hashes are allowed.</p>
<p>For example:</p>
<pre>
        package Test;</pre>
<pre>
        our $Counter = 0;
        our $Scalar = 'Scalar';
        our @Array = qw(A r r a y);
        our %Hash = (H =&gt; 'a', s =&gt; 'h', e =&gt; 'd');
        our $SRef = \$Scalar;
        our $ARef = \@Array;
        our %HRef = \%Hash;</pre>
<pre>
        PlPN-&gt;RegisterData('$Test::Counter');
        PlPN-&gt;RegisterData('$Test::Scalar');
        PlPN-&gt;RegisterData('@Test::Array');
        PlPN-&gt;RegisterData('%Test::Hash');
        PlPN-&gt;RegisterData('$Test::SRef');
        PlPN-&gt;RegisterData('$Test::ARef');
        PlPN-&gt;RegisterData('$Test::HRef');
        PlPN-&gt;RegisterData('$Test::Arrray[0]');
        PlPN-&gt;RegisterData('$Test::ARef-&gt;[0]');
        PlPN-&gt;RegisterData('$Test::Hash{H}');
        PlPN-&gt;RegisterData('$Test::HRef-&gt;{H}');</pre>
<p>The data is transformed into a sequence of bytes via <code>Storable::freeze</code> and
restored via <code>Storable::thaw</code>.  It is restored after all scripts have been
read.</p>
<p>There is no guarantee it will handle objects correctly. If you wish to
preserve an object, you should supply the hooks desribed in <em>Storable</em>.</p>
<p>Another option is to register events for <a href="#onbeforecycle">OnBeforeCycle</a> and
<a href="#onaftercycle">OnAfterCycle</a> and do any special processing there.</p>
</dd>
<dt><strong><a name="currentdocuments" class="item">CurrentDocuments()</a></strong></dt>

<dd>
<p>This returns an arrayref of all the current documents. It should not be
necessary if you are using <a href="#registerevent">RegisterEvent</a>, but if you are creating your
own event sinks, then after the interpreter is cycled you may need to be
able to access the existing documents in order to hook your event sinks back
up.</p>
</dd>
</dl>
<p>
</p>
<hr />
<h1><a name="events">EVENTS</a></h1>
<dl>
<dt><strong>OnBeforeCycle()</strong></dt>

<dt><strong>OnAfterCycle()</strong></dt>

<dd>
<p>The default versions of these events. They save and restore registered data,
and call any registered subrefs for the events. You should never call them
yourself, except maybe from a child class version of the same event.</p>
</dd>
</dl>
<p>
</p>
<hr />
<h1><a name="utility_methods">UTILITY METHODS</a></h1>
<dl>
<dt><strong><a name="alert" class="item">alert($message, $flags = 0, $title = 'PlPN')</a></strong></dt>

<dd>
<p>Shows a windows MessageBox. Since this is mainly intended as a debugging
tool, no constants are provided for <code>$flags</code>, but you can look them up
online if you really want them.</p>
</dd>
<dt><strong><a name="report_refcount" class="item">report_refcount($perlvar, $where)</a></strong></dt>

<dd>
<p>Another debugging tool. This displays the reference count for a perl scalar
variable. Its purpose is to make sure the XS code that glues the Perl to the
C++ extension is properly handling reference counts. If you are getting
strange error message when passing variables to functions defined in XS, or
using variables created by XS, this might help track down the bug.</p>
</dd>
<dt><strong><a name="valid_package_name" class="item">valid_package_name($string)</a></strong></dt>

<dd>
<p>Called when <code>eval</code>ing a script file, this function generates a unique
package name; the script file is then wrapped into that package to protect
the <code>main</code> namespace.</p>
</dd>
<dt><strong><a name="eval_file" class="item">eval_file($filename)</a></strong></dt>

<dd>
<p>Called to <code>eval</code> a script file, this function wraps the file into a unique
package name to protect the <code>main</code> namespace.</p>
</dd>
</dl>
<p>
</p>
<hr />
<h1><a name="utility_functions">UTILITY FUNCTIONS</a></h1>
<p>Note that these are functions, not methods.</p>
<dl>
<dt><strong><a name="init" class="item">init()</a></strong></dt>

<dd>
<p>This is called by system immediately after loading <code>PlPN.pm</code>. It checks for
the file <code>plpn.init</code> in the scripts folder and loads it if it finds it. If 
<code>plpn.init</code> returns a true value, or if it is not found, then all files
from the scripts folder with the extension <code>.pl</code> will be loaded.</p>
<p>You can't redefine this function from your own code. Or rather, you can, but
it will do you no good. It is called only once, before any of your code has
been run.</p>
</dd>
<dt><strong><a name="redirect_stdout" class="item">redirect_stdout($sref)</a></strong></dt>

<dt><strong><a name="restore_stdout" class="item">restore_stdout()</a></strong></dt>

<dd>
<p>These are called by the system when the printed output of a script is
desired instead of the return value. <code>$sref</code> is a scalar ref which will
hold the printed output.</p>
<p>You could redefine these from your own code, but you probably shouldn't.</p>
</dd>
</dl>
<p>
</p>
<hr />
<h1><a name="copyright_and_licence">COPYRIGHT and LICENCE</a></h1>
<p>Copyright (c) 2012 Sean Healy. All rights reserved.</p>
<p>This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.</p>

</body>

</html>
